from xmldict.xmltools import read_dict, write_dict
from xml.dom import minidom

def test_read(test_sets):
	from xml.parsers.expat import ExpatError
	for patterns, fun in test_sets:
		for xml,result in patterns:
			try:
				doc = minidom.parseString(xml)
				node = doc.documentElement
				out = fun(node)
				if result != out:
					raise AssertionError('\n\tXML: %s\n\tExpected: %r\n\tGotten: %r'%(xml, result, out))
			except ExpatError,e:
				print 'Wrong XML: "%s"'%xml
				raise

def test_write(test_sets):
	newset = []
	for patterns, fun in test_sets:
		vals = []
		for xml, result in patterns:
			doc = minidom.parseString(xml)
			root = doc.documentElement
			for i in root.childNodes[:]:     # remove any childs ...
				root.removeChild(i)
			for i in root.attributes.keys(): # ...and attributes
				root.removeAttribute(i)
			write_dict(doc, root, result)
			vals.append( (doc.toxml(), result) )
		newset.append((vals, fun))
	test_read(tuple(newset))



tests = (
(''' <a></a> ''', {}),                   # empty XML file => empty dict
(''' <a>1</a> ''', {u'@':u'1'}),         # only text inside
(''' <a><b>1</b></a> ''', {u'b':u'1'}),      # one nested element with some data inside
(''' <a b="2">1</a> ''', {u'@':{u'@': u'1', u'b': u'2'}}),
(''' <a><b>1</b><b>2</b><b>3</b></a> ''', {u'b':[u'1',u'2',u'3']}),
(''' <a>
	<b><c>1</c></b>
	<d><c>2</c></d>
</a> ''', {u'b':{u'c':u'1'},u'd':{u'c':u'2'}}),
(''' <a>
	<c> <b>1</b> </c>
	<c> <d>2</d> </c>
</a> ''',  {u'c':[{u'b':u'1'},{u'd':u'2'}]}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
)
tests_force = (
(''' <a></a> ''',{}),                   # empty XML file => empty dict
(''' <a>1</a> ''', {u'@':{u'@':u'1'}}),         # only text inside
(''' <a><b>1</b></a> ''', {u'b':{u'@':{u'@':u'1'}}}),      # one nested element with some data inside
(''' <a b="2">1</a> ''', {u'@':{u'@': u'1', u'b': u'2'}}),
(''' <a><b>1</b><b>2</b><b>3</b></a> ''', {u'b':[{u'@':{u'@':u'1'}},{u'@':{u'@':u'2'}},{u'@':{u'@':u'3'}},]}),
(''' <a>
	<b><c>1</c></b>
	<d><c>2</c></d>
</a> ''', {u'b':{u'c':{u'@':{u'@':u'1'}},},u'd':{u'c':{u'@':{u'@':u'2'}},}}),
(''' <a>
	<c> <b>1</b> </c>
	<c> <b>2</b> </c>
</a> ''', {u'c':[{u'b':{u'@':{u'@':u'1'}}},{u'b':{u'@':{u'@':u'2'}}}]}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
(''' <a></a> ''', {}),
)

TESTS = ((tests,read_dict), (tests_force, lambda d: read_dict(d, True, True)))
def main():
	test_read(TESTS)
	test_write(TESTS)

if __name__ == '__main__': main()
